﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace TSQLDocumentor
{
    public static class CommentExtractor
    {
        public static string ExtractTagContents(string AllText, bool IncludeCode)
        {
            string Contents = "";

            bool PassedValidation = false;
            string ValidationMessage;
            var Tags = Regex.Matches(AllText, @"(<[^>\s,]+?>)+?");
            if (Tags.Count > 0)
            {
                PassedValidation = true;
                ValidateMatchingTags(Tags, out PassedValidation, out ValidationMessage);
                Contents += ValidationMessage;
            }

            if (PassedValidation)
            {
                string StartTag = "";

                String h1Regex = @"(?<StartTag><[^>\s,]*?>)" + "(?<TagContents>.*?)" + @"(?<EndTag><\/[^>\s,]*?>)";
                MatchCollection mc = Regex.Matches(AllText, h1Regex, RegexOptions.Singleline);
                foreach (Match ContentMatch in mc)
                {
                    StartTag = ContentMatch.Groups["StartTag"].Value;
                    
                    int AdditionalHeaderCounter = StartTag.Count(hc => hc == '#');
                    StartTag = StartTag.Replace("<", "").Replace(">", "").Replace("_", " ").Replace("#", "");

                    if (IncludeCode)
                    {
                        Contents += "\n" + string.Format("{1} {0} {1}", StartTag, new string('#', 4 - AdditionalHeaderCounter));
                        if (StartTag.ToUpper() == "CODE")
                            Contents += "\n\n\t" + ContentMatch.Groups["TagContents"].Value;
                        else
                            Contents += "\n" + ContentMatch.Groups["TagContents"].Value.Replace("\t", "");
                    }
                    else
                    {
                        if (StartTag.ToUpper() != "CODE")
                        {
                            Contents += "\n" + string.Format("{1} {0} {1}", StartTag, new string('#', 4 - AdditionalHeaderCounter));
                            Contents += "\n" + ContentMatch.Groups["TagContents"].Value.Replace("\t", "");
                        }
                    }

                    Contents += "\n";

                }
            }
            return Contents;
        }

        public static void ValidateMatchingTags(MatchCollection Tags, out bool PassedValidation, out string ValidationMessage)
        {
            ValidationMessage = null;
            PassedValidation = true;
            bool? FoundMismatch = null;

            List<string> Exclusions = new List<string>();
            Exclusions.Add("<br>");
            Exclusions.Add("<String>");
            Exclusions.Add("<DateTime>");
            Exclusions.Add("<Decimal>");
            Exclusions.Add("<Int32>");
            Exclusions.Add("<Int16>");
            Exclusions.Add("<Byte>");
            Exclusions.Add("<Boolean>");
            Exclusions.Add("<Object>");

            foreach (Match TagMatch in Tags)
            {
                if (!Exclusions.Select(e => e.ToUpper()).Contains(TagMatch.Value.ToUpper()))
                {
                    if (FoundMismatch == null)
                        FoundMismatch = false;

                    if (!TagMatch.Value.Contains("/"))
                    {
                        if (!Tags.Cast<Match>().Select(m => m.Value.ToUpper()).Contains(TagMatch.Value.ToUpper().Replace("<", "</")))
                        {
                            FoundMismatch = true;
                            ValidationMessage += "\n" + string.Format("__Ending Tag Not Found__ _{0}_", TagMatch.Value.Replace("<", "").Replace(">", ""));
                        }
                    }

                    if (TagMatch.Value.Contains("/"))
                    {
                        if (!Tags.Cast<Match>().Select(m => m.Value.ToUpper()).Contains(TagMatch.Value.ToUpper().Replace("</", "<")))
                        {
                            FoundMismatch = true;
                            ValidationMessage += "\n" + string.Format("__Start Tag Not Found__ _{0}_", TagMatch.Value.Replace("</", "").Replace(">", ""));
                        }
                    }
                }
            }

            if (FoundMismatch == null || FoundMismatch == true)
                PassedValidation = false;
        }

    }
}
